<template>
  <div class="tree-select-main">
    <div
      class="input-main"
      ref="inputRef"
      @click="isShow = !isShow"
      :class="{ 'input-main-select': isShow }"
    >
      <div class="select-layout">
        <input v-model="current" type="text" :placeholder="placeholder" />
        <div class="icon-triangle" :class="{ 'icon-open': isShow }"></div>
      </div>
      <div class="select-layout-shade"></div>
    </div>
    <transition name="drop">
      <div class="tree-main" v-if="isShow" ref="treeRef">
        <CascaderTree
          :tree-options="treeSelectData"
          @click-item="clickItem"
          @expand="treeExpand"
          v-model="treeValue"
          v-model:expanded-keys="expandedKeys"
          v-bind:expandeds="childExpandeds"
        />
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { TreeOption } from './CascaderTree.vue'

export interface TreeSelectOption extends TreeOption {}

interface Props {
  treeSelectData: Array<TreeSelectOption>
  modelValue?: string | number
  placeholder?: string
  expandedKeys?: Array<string | number>
}

const props = withDefaults(defineProps<Props>(), {
  treeSelectData: () => [],
  placeholder: '请选择',
  expandedKeys: () => []
})

const emit = defineEmits(['update:modelValue', 'update:expandedKeys', 'selectItem', 'expand'])

const isShow = ref(false)
const inputRef = ref<HTMLDivElement>()
const treeRef = ref<HTMLDivElement>()
const current = ref('')
const treeValue = ref(props.modelValue)
const expandedKeys = ref(props.expandedKeys)
const childExpandeds = ref([])

const clickItem = (args: any) => {
  const { item, expandeds } = args
  current.value = expandeds?.map((i: TreeSelectOption) => i.label).join('/')
  isShow.value = false
  emit('update:modelValue', item.key)
  emit('selectItem', { item, expandeds })
}
const treeExpand = () => {
  emit('expand', expandedKeys.value)
}

const handleClickOutside = (e: any) => {
  if (treeRef.value && !treeRef.value.contains(e.target) && !inputRef.value?.contains(e.target)) {
    isShow.value = false
  }
}

const init = (list: Array<TreeSelectOption>) => {
  list.forEach((value) => {
    if (props.expandedKeys.includes(value.key)) {
      current.value = current.value ? `${current.value}/${value.label}` : value.label
      if (value.children) {
        init(value.children)
      }
    }
  })
}

onMounted(() => {
  window.addEventListener('click', handleClickOutside)

  init(props.treeSelectData)
})

onBeforeUnmount(() => {
  window.removeEventListener('click', handleClickOutside)
})
</script>

<style scoped lang="scss">
.tree-select-main {
  width: 210px;
  position: relative;

  .input-main {
    display: flex;
    background: #fff;
    border-radius: 6px;
    width: inherit;
    height: 36px;
    position: relative;
    border: 1px solid #d9d9d9;
    transition: 0.4s;

    &:hover {
      border-color: $main-color;
    }

    .select-layout {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-left: 10px;
      font-size: 14px;

      .icon-triangle {
        width: 6px;
        height: 6px;
        border-top: 3px solid transparent;
        border-left: 3px solid transparent;
        border-right: 3px solid #2c2d30;
        border-bottom: 3px solid #2c2d30;
        margin-right: 12px;
        transform: rotate(-45deg);
        transition: 0.4s;
      }

      .icon-open {
        transform: rotate(45deg);
      }
    }

    .select-layout-shade {
      position: absolute;
      width: 100%;
      height: 100%;
      cursor: pointer;
    }

    input {
      inset-inline: none;
      border: none;
      outline: none;
      display: block;
      height: 18px;
      padding: 0;
      width: 170px;
      font-size: 14px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;

      &::-ms-input-placeholder {
        line-height: normal;
        font-size: 12px;
      }

      &::-webkit-input-placeholder {
        line-height: normal;
        font-size: 12px;
      }
    }
  }

  .input-main-select {
    border-color: $main-color;
  }

  .tree-main {
    overflow: hidden;
    transform: rotate(0deg);
    max-height: 210px;
    position: absolute;
    background: #fff;
    box-shadow: 0 2px 10px 0 #c5c9cf80;
    overflow-y: auto;
    padding: 6px 0;

    &::-webkit-scrollbar {
      width: 5px;
    }

    &::-webkit-scrollbar-track {
      background: #fff;
      border-radius: 2px;
    }

    &::-webkit-scrollbar-thumb {
      background: #d9dce3;
      border-radius: 2px;
    }
  }
}

.drop-enter-active {
  animation: drop-anim 0.4s;
}

.drop-leave-active {
  animation: drop-anim 0.4s reverse;
}

@keyframes drop-anim {
  from {
    transform: translateY(-20px);
    opacity: 0;
  }
}
</style>
